/**
 * This file is Copyright © 2008 Software Craftsmen Limited. All Rights Reserved.
 */
package com.softwarecraftsmen.generators;

import com.softwarecraftsmen.functors.*;
import com.softwarecraftsmen.functors.Boolean;
import com.softwarecraftsmen.generators.summarisers.Summariser;
import org.jetbrains.annotations.NotNull;

public abstract class AbstractGenerator<V> implements Generator<V>
{
	public void each(final @NotNull UnaryFunctor<V> eachFunctor)
	{
		Optional<V> nextValue = next();
		while(nextValue.hasSomething().isTrue())
		{
			eachFunctor.closure(nextValue.value());
		}
	}

	@NotNull
	public Generator<V> identity(final @NotNull UnaryFunctor<V> eachFunctor)
	{
		return new IdentityGenerator<V>(this, eachFunctor);
	}

	public <T> T summarise(final @NotNull Summariser<V, T> summariser)
	{
		each(summariser);
		return summariser.summary();
	}

	@NotNull
	public <T> Generator<T> transform(final @NotNull UnaryReturningFunctor<V, T> transformFunctor)
	{
		return new TransformGenerator<V, T>(this, transformFunctor);
	}

	@NotNull
	public Generator<V> where(final @NotNull UnaryReturningFunctor<V, com.softwarecraftsmen.functors.Boolean> whereFunctor)
	{
		return new WhereGenerator<V>(this, whereFunctor);
	}

	@NotNull
	public Optional<V> firstMatchWhere(@NotNull final UnaryReturningFunctor<V, Boolean> whereFunctor)
	{
		return where(whereFunctor).next();
	}
}
